/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Hilos;

import ClasesBase.Jugador;
import Extras.Mensajes;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.LinkedList;
import Gestores.GestorServidor;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Francisco
 */
public class SocketServidor extends Thread {

    private GestorServidor gestorServidor;
    private LinkedList<HiloServidor> hilosServidor;
    private boolean comenzoPartida;
    private ServerSocket serverSocket;

    public SocketServidor(GestorServidor gestorServidor) {
        comenzoPartida = false;
        this.gestorServidor = gestorServidor;
        this.hilosServidor = new LinkedList<>();
    }

    public void run() {
        serverSocket = null;
        boolean listening = true;

        try {
            serverSocket = new ServerSocket(5000);
            System.out.println("Server en linea...");
            gestorServidor.setTodoOk(true);
        } catch (IOException ex) {
            gestorServidor.setTodoOk(false);
        }
        gestorServidor.notificar();
        if (gestorServidor.getTodoOk()) {
            while (listening) {
                try {
                    HiloServidor hiloServidor = new HiloServidor(serverSocket.accept(), this);
                    hilosServidor.add(hiloServidor);
                    hiloServidor.start();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    public void add(String nickname) {
        gestorServidor.addJugador(nickname);
        gestorServidor.llenarTablaEnEspera();
        this.crearMensajeJugadores();
    }

    public void eliminar(String nickname) {
        gestorServidor.eliminarJugador(nickname);
        gestorServidor.llenarTablaEnEspera();
        this.crearMensajeJugadores();
        this.eliminarHilo(nickname);
    }

    public LinkedList<Jugador> getJugadores() {
        return gestorServidor.getJugadores();
    }

    public void crearMensajeJugadores() {
        for (HiloServidor hiloServidor : hilosServidor) {
            hiloServidor.crearMensajeJugadores();
        }
    }

    private void eliminarHilo(String nickname) {
        for (int i = 0; i < hilosServidor.size(); i++) {
            HiloServidor hiloSer = hilosServidor.get(i);
            if (hiloSer.getNickname().equals(nickname)) {
                hilosServidor.remove(i);
                hiloSer.parar();
                break;
            }
        }
    }

    public void cerrarServidor() {
        try {
            for (HiloServidor hiloServidor : hilosServidor) {
                hiloServidor.cerrarServidor();
            }
            this.stop();
            this.serverSocket.close();
            //gestorServidor.setPrincipalVisible(true);
        } catch (IOException ex) {
            Logger.getLogger(SocketServidor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void comenzarPartida() {
        comenzoPartida = true;
        for (HiloServidor hiloServidor : hilosServidor) {
            hiloServidor.comenzarPartida();
        }
    }

    public void aniadirResultadoComienzo(int resultado, String nickname) {
        gestorServidor.aniadirResultadoComienzo(resultado, nickname);
    }

    public void tirarDados(String nickname) {
        for (HiloServidor hiloServidor : hilosServidor) {
            hiloServidor.enviarMensaje(nickname + "-TiraLosDados-");
        }
    }

    public boolean getComenzoPartida() {
        return comenzoPartida;
    }

    public void cerrarUltimoHilo() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public void informarDadosJugador(String nickname, int dado1, int dado2) {
        gestorServidor.informarResultadoDadosJugador(nickname, dado1, dado2);
    }

    public void enviarMensajeDeCompra(String mensajeGeneral, String mensajeComprar, String nickname) {
        for (HiloServidor hiloServidor : hilosServidor) {
            hiloServidor.enviarMensaje(mensajeGeneral);
            if (hiloServidor.getNickname().compareTo(nickname) == 0) {
                hiloServidor.enviarMensaje(mensajeComprar);
            }
        }
    }

    public void enviarMensaje(String mensaje) {
        for (HiloServidor hiloServidor : hilosServidor) {
            hiloServidor.enviarMensaje(mensaje);
        }
    }

    public void jugadorAbandono(String nickname) {
        for (HiloServidor hiloServidor : hilosServidor) {
            if (nickname.compareTo(hiloServidor.getNickname()) != 0) {
                hiloServidor.enviarMensaje(nickname + "-CerroElJuego-");
            }
        }
        cerrarServidor();
        gestorServidor.setPrincipalVisible(true);
    }

    public boolean existeJugador(String nickname) {
        return gestorServidor.existeJugador(nickname);
    }

    public void enviarMensajeComprar(String mensaje, String nickname, String terreno) {
        int i;
        for (i = 0; hilosServidor.get(i).getNickname().compareTo(nickname) != 0; i++);
        mensaje = terreno + "-PreguntarComprarTerreno-" + mensaje;
        hilosServidor.get(i).enviarMensaje(mensaje);
    }

    public void enviarMensajeSubasta(String nombreTerreno, String idCasillero, String nicknameSiguienteAOfertar, String nicknameAMostrarEnOferta, String precio) {
        String mensaje;
        for (HiloServidor hiloServidor : hilosServidor) {
            mensaje = idCasillero + "-Subasta-" + nombreTerreno + "-" + nicknameSiguienteAOfertar + "-" + nicknameAMostrarEnOferta + "-" + precio;
            hiloServidor.enviarMensaje(mensaje);
        }
    }

    public void jugadorCompra(String nickname, String idTerreno) {
        gestorServidor.jugadorCompra(nickname, idTerreno);
    }

    public void subasta(String nickname, String idTerreno) {
        gestorServidor.comenzarSubasta(nickname, idTerreno);
    }

    public void enviarMensajeImpuesto(String mensaje, String nickname) {
        for (int i = 0; i < hilosServidor.size(); i++) {
            if (hilosServidor.get(i).getNickname().compareTo(nickname) != 0) {
                mensaje = "Impuesto Sobre Ingreso.El jugador " + nickname + " pagó al banco $200.";
                mensaje = nickname + "-NoImpuesto-" + mensaje;
                hilosServidor.get(i).enviarMensaje(mensaje);
            } else {
                mensaje = nickname + "-Impuesto-" + mensaje;
                hilosServidor.get(i).enviarMensaje(mensaje);
            }
        }
    }

    public void enviarMensajeSinJugador(String mensajeGeneral, String nickname) {
        for (HiloServidor hiloServidor : hilosServidor) {
            if (hiloServidor.getNickname().compareTo(nickname) != 0) {
                hiloServidor.enviarMensaje(mensajeGeneral);
            }
        }
    }

    public void procesarOferta(String nickname, String oferta) {
        gestorServidor.procesarOferta(nickname, oferta);
    }

    public void enviarMensajeConParticular(String mensajeParticular, String nickname, String mensajeGeneralHistorial) {
        for (int i = 0; i < hilosServidor.size(); i++) {
            if (hilosServidor.get(i).getNickname().compareTo(nickname) == 0) {
                hilosServidor.get(i).enviarMensaje(mensajeParticular + ";" + mensajeGeneralHistorial);
            } else {
                hilosServidor.get(i).enviarMensaje(mensajeGeneralHistorial);
            }
        }
    }

    public void enviarMensajeSinParticular(String mensajeParticular, String nickname, String mensajeGeneralHistorial) {
        for (int i = 0; i < hilosServidor.size(); i++) {
            if (hilosServidor.get(i).getNickname().compareTo(nickname) == 0) {
                hilosServidor.get(i).enviarMensaje(mensajeGeneralHistorial);
            } else {
                hilosServidor.get(i).enviarMensaje(mensajeGeneralHistorial + ";" + mensajeParticular);
            }
        }
    }

    public void enviarMensajeEnParticular(String nickname, String mensajeParticular) {
        for (int i = 0; i < hilosServidor.size(); i++) {
            if (hilosServidor.get(i).getNickname().compareTo(nickname) == 0) {
                hilosServidor.get(i).enviarMensaje(mensajeParticular);
                return;
            }
        }
    }

    public void cobroAlquilerServicio(int dado1, int dado2, String nickDuenioServicio, String nickname) {
        gestorServidor.cobroAlquilerServicio(dado1, dado2, nickDuenioServicio, nickname);
    }

    public void informarPosicionJugador(String nickname, int posicion) {
        gestorServidor.informarPosicionJugador(nickname, posicion);
    }

    public void enviarMensajesParticularYOtros(String mensajePart, String nickname, String mensajeSinJugador) {
        for (int i = 0; i < hilosServidor.size(); i++) {
            if (hilosServidor.get(i).getNickname().compareTo(nickname) == 0) {
                hilosServidor.get(i).enviarMensaje(mensajePart);
            } else {
                hilosServidor.get(i).enviarMensaje(mensajeSinJugador);
            }
        }
    }

    public void salirCarcel(String nickname, String saleCarcel) {
        gestorServidor.salirCarcel(nickname, saleCarcel);
    }

    void listarPropiedadesJugador(String nickname, boolean esPorPreso) {
        gestorServidor.listarPropiedadesDeshipotecadasJugador(nickname, esPorPreso);
    }

    void hipotecar(String nickname, String propiedades, boolean finalH) {
        gestorServidor.hipotecar(nickname, propiedades, finalH);
    }

    void listarPropiedadesHipotecadas(String nickname) {
        gestorServidor.listarPropiedadesHipotecadasJugador(nickname);
    }

    void deshipotecar(String nickname, String propiedades) {
        gestorServidor.deshipotecar(nickname, propiedades);
    }

    void canceloAccion(String nickname) {
        gestorServidor.canceloAccion(nickname);
    }

    void listarPropiedadesConstruccion(String nickname) {
        gestorServidor.listarPropiedadesConstruccion(nickname);
    }

    void construirCasas(String propiedades, String nickname, boolean esFinal) {
        gestorServidor.construirCasas(propiedades, nickname, esFinal);
    }

    void listarPropiedadesDeconstruccion(String nickname) {
        gestorServidor.listarPropiedadesDeconstruccion(nickname);
    }

    void comprarCasilla(String nickname, String propiedad) {
        gestorServidor.comprarCasilla(nickname, propiedad);
    }

    void subastaC(String nick, String idTerreno) {
        gestorServidor.comenzarSubastaC(nick, idTerreno);
    }

    void hipotecoPorPreso(String nick) {
        gestorServidor.hipotecoPorPreso(nick);
    }

    void hipotecaPorSubasta(String nick) {
        gestorServidor.hipotecaPorSubasta(nick);
    }

    void noCompraPorSub(String nick) {
        gestorServidor.noCompraPorSub(nick);
    }

    void listarPropiedadesJugadorParticular(String nick, String nickPart) {
        gestorServidor.listarPropiedadesJugadorParticular(nick, nickPart);
    }

    public void enviarMensajeSinPartConPartATodos(String nickname, String mensajeEnParticular, String mensajeSinParticular, String mensajeATodos) {
        if (!mensajeATodos.isEmpty()) {
            if (!mensajeEnParticular.isEmpty()) {
                if (mensajeEnParticular.contains("MostrarTarjeta")) {
                    mensajeEnParticular += ";" + mensajeATodos;
                } else {
                    mensajeEnParticular = mensajeATodos + ";" + mensajeEnParticular;
                }
            } else {
                mensajeEnParticular += mensajeATodos;
            }
            if (!mensajeSinParticular.isEmpty()) {
                mensajeSinParticular += ";";
            }
            mensajeSinParticular += mensajeATodos;
        }
        for (HiloServidor hiloServidor : hilosServidor) {
            if (hiloServidor.getNickname().compareTo(nickname) == 0) {
                hiloServidor.enviarMensaje(mensajeEnParticular);
            } else {
                hiloServidor.enviarMensaje(mensajeSinParticular);
            }
        }
    }

    void propuestaComerciar(String nick, String propuesta) {
        gestorServidor.propuestaComerciar(nick, propuesta);
    }

    void respuestaPropuestaComerciar(String nick, String propuesta) {
        gestorServidor.respuestaPropuestaComerciar(nick, propuesta);
    }

    void pagarPorHipoConstru(String nick) {
        gestorServidor.pagarPorHipoConstru(nick);
    }

    public void close() {
        try {
            this.serverSocket.close();
        } catch (IOException ex) {
            Logger.getLogger(SocketServidor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void preguntarCierre(String nickname) {
        for (HiloServidor hiloServidor : hilosServidor) {
            if (hiloServidor.getNickname().compareTo(nickname) == 0) {
                if (getComenzoPartida()) {
                    hiloServidor.enviarMensaje(nickname + "-preguntarCierre-no");
                    break;
                }
                hiloServidor.enviarMensaje(nickname + "-preguntarCierre-si");
                break;
            }
        }
    }
}
